﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Nirvana
{
    /// <summary>
    /// 修改text的字体深度阴影效果，可以实现3D字体效果
    /// </summary>
    [RequireComponent(typeof(Text))]
    [AddComponentMenu("Nirvana/UI/Effect/Depth Effect")]
    public class UIDepthEffect : BaseMeshEffect
    {
        [SerializeField]
        private Color effectColor = Color.black;
        [SerializeField]
        private Vector2 directionAndDepth = new Vector2(-1f, 1f);
        [SerializeField]
        private Vector2 depthPerspectiveStrength = new Vector2(0, 0);
        [SerializeField]
        private bool onlyInitialCharactersGenerateDepth = true;
        [SerializeField]
        private bool useGraphicAlpha = true;

        private Vector2 distXY = Vector2.zero;
        private Vector2 startPos = Vector2.zero;
        private Vector2 endPos = Vector2.zero;


#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            if (base.graphic != null)
            {
                base.graphic.SetVerticesDirty();
            }
        }
#endif

        public override void ModifyMesh(VertexHelper vh)
        {
            if (!this.IsActive() || vh.currentVertCount <= 0)
            {
                return;
            }

            List<UIVertex> tempList = VertexLists.Get();
            vh.GetUIVertexStream(tempList);
            List<UIVertex> newlist = ModifyTextVertexs(tempList);
            if (newlist != null)
            {
                vh.Clear();
                vh.AddUIVertexTriangleStream(newlist);
            }
            VertexLists.Set(newlist);
        }

        private List<UIVertex> ModifyTextVertexs(List<UIVertex> _list)
        {
            int totalCount = _list.Count;
            Text txt = GetComponent<Text>();
            List<UIVertex> newList = new List<UIVertex>();
            if (this.onlyInitialCharactersGenerateDepth)
            {
                newList = _list.GetRange(_list.Count - txt.cachedTextGenerator.characterCountVisible * 6, txt.cachedTextGenerator.characterCountVisible * 6);
            }
            else
            {
                newList = _list;
            }

            if (newList.Count == 0) return null;
            if (this.depthPerspectiveStrength.x != 0f || this.depthPerspectiveStrength.y != 0f)
            {
                this.startPos = newList[0].position;
                this.endPos = newList[newList.Count - 1].position;
                for(int i = 0; i < newList.Count; i++)
                {
                    //找左上顶点
                    if(newList[i].position.x < this.startPos.x)
                    {
                        this.startPos.x = newList[i].position.x;
                    }

                    if (newList[i].position.y > this.startPos.y)
                    {
                        this.startPos.y = newList[i].position.y;
                    }
                    //右下顶点
                    if (newList[i].position.x > this.endPos.x)
                    {
                        this.endPos.x = newList[i].position.x;
                    }

                    if (newList[i].position.y < this.endPos.y)
                    {
                        this.endPos.y = newList[i].position.y;
                    }

                }

                this.distXY = new Vector2(this.endPos.x - this.startPos.x, this.startPos.y - this.endPos.y);
            }

            this.ModifyVertex(newList, this.effectColor, 0, newList.Count, this.directionAndDepth.x, this.directionAndDepth.y, 0.25f);
            this.ModifyVertex(newList, this.effectColor, 0, newList.Count, this.directionAndDepth.x, this.directionAndDepth.y, 0.5f);
            this.ModifyVertex(newList, this.effectColor, 0, newList.Count, this.directionAndDepth.x, this.directionAndDepth.y, 0.75f);
            this.ModifyVertex(newList, this.effectColor, 0, newList.Count, this.directionAndDepth.x, this.directionAndDepth.y, 1f);

            if (this.onlyInitialCharactersGenerateDepth)
            {
                newList.RemoveRange(newList.Count - txt.cachedTextGenerator.characterCountVisible * 6, txt.cachedTextGenerator.characterCountVisible * 6);
                newList.AddRange(_list);
            }
            if (this.HasComponent<UIMaterialEffect>())
            {
                for(int i = 0; i < newList.Count - totalCount; i++)
                {
                    UIVertex _vert = newList[i];
                    _vert.uv1 = new Vector2(0, 0);
                    newList[i] = _vert;

                }
            }

            return newList;
        }

        private void ModifyVertex(List<UIVertex> _list,Color32 effectColor,int startpos,int Count, float xOffset, float yOffset,float offset)
        {
            for(int i = startpos; i < Count; i++)
            {
                UIVertex vertex = _list[i];
                _list.Add(vertex); //重影
                Vector3 pos = vertex.position;
                pos.x += xOffset * offset;
                if(this.depthPerspectiveStrength.x != 0)
                {
                    pos.x -= this.depthPerspectiveStrength.x * offset * ((pos.x - this.startPos.x) / this.distXY.x - 0.5f);
                }
                pos.y += yOffset * offset;
                if (this.depthPerspectiveStrength.y != 0)
                {
                    pos.y += this.depthPerspectiveStrength.y * offset * (( this.startPos.y - pos.y) / this.distXY.y - 0.5f);
                }
                vertex.position = pos;
                if (this.useGraphicAlpha)
                {
                    effectColor.a = (byte)(effectColor.a * _list[i].color.a / byte.MaxValue);
                }

                vertex.color = effectColor;
                _list[i] = vertex;
            }
        }
    }

}

